home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / rogue / level.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-05-13  |  17.1 KB  |  841 lines

  1. /*
  2.  * level.c
  3.  *
  4.  * This source herein may be modified and/or distributed by anybody who
  5.  * so desires, with the following restrictions:
  6.  *    1.)  No portion of this notice shall be removed.
  7.  *    2.)  Credit shall not be taken for the creation of this source.
  8.  *    3.)  This code is not to be traded, sold, or used for personal
  9.  *         gain or profit.
  10.  *
  11.  */
  12.  
  13. #ifndef CURSES
  14. #include <curses.h>
  15. #endif CURSES
  16. #include "rogue.h"
  17.  
  18. #define swap(x,y) {t = x; x = y; y = t;}
  19.  
  20. short cur_level = 0, max_level = 1, cur_room;
  21. char *new_level_message = 0;
  22. short party_room = NO_ROOM;
  23. short r_de;
  24.  
  25. long level_points[MAX_EXP_LEVEL] = {
  26.           10L,
  27.           20L,
  28.           40L,
  29.           80L,
  30.          160L,
  31.          320L,
  32.          640L,
  33.         1300L,
  34.         2600L,
  35.         5200L,
  36.        10000L,
  37.        20000L,
  38.        40000L,
  39.        80000L,
  40.       160000L,
  41.       320000L,
  42.      1000000L,
  43.      3333333L,
  44.      6666666L,
  45.       MAX_EXP,
  46.     99900000L
  47. };
  48.  
  49. char random_rooms[MAXROOMS+1] = "\003\007\005\002\010\006\001\004\0";
  50.  
  51. extern boolean being_held, wizard, detect_monster;
  52. extern boolean see_invisible;
  53. extern short bear_trap, levitate, extra_hp, less_hp, cur_room;
  54. extern short party_counter;
  55.  
  56. make_level()
  57. {
  58.     short i, j;
  59.     short must_exist1, must_exist2, must_exist3;
  60.     boolean big_room;
  61.  
  62.     if (cur_level < LAST_DUNGEON) {
  63.         cur_level++;
  64.     }
  65.     if (cur_level > max_level) {
  66.         max_level = cur_level;
  67.     }
  68.     must_exist1 = get_rand(0, 5);
  69.  
  70.     switch(must_exist1) {
  71.     case 0:
  72.         must_exist1 = 0;
  73.         must_exist2 = 1;
  74.         must_exist3 = 2;
  75.         break;
  76.     case 1:
  77.         must_exist1 = 3;
  78.         must_exist2 = 4;
  79.         must_exist3 = 5;
  80.         break;
  81.     case 2:
  82.         must_exist1 = 6;
  83.         must_exist2 = 7;
  84.         must_exist3 = 8;
  85.         break;
  86.     case 3:
  87.         must_exist1 = 0;
  88.         must_exist2 = 3;
  89.         must_exist3 = 6;
  90.         break;
  91.     case 4:
  92.         must_exist1 = 1;
  93.         must_exist2 = 4;
  94.         must_exist3 = 7;
  95.         break;
  96.     case 5:
  97.         must_exist1 = 2;
  98.         must_exist2 = 5;
  99.         must_exist3 = 8;
  100.         break;
  101.     }
  102.     big_room = ((cur_level == party_counter) && rand_percent(1));
  103.     if (big_room) {
  104.         make_room(BIG_ROOM, 0, 0, 0);
  105.     } else {
  106.         for (i = 0; i < MAXROOMS; i++) {
  107.             make_room(i, must_exist1, must_exist2, must_exist3);
  108.         }
  109.     }
  110.     if (!big_room) {
  111.         add_mazes();
  112.  
  113.         mix_random_rooms();
  114.  
  115.         for (j = 0; j < MAXROOMS; j++) {
  116.  
  117.             i = random_rooms[j];
  118.  
  119.             if (i < (MAXROOMS-1)) {
  120.                 (void) connect_rooms(i, i+1);
  121.             }
  122.             if (i < (MAXROOMS-3)) {
  123.                 (void) connect_rooms(i, i+3);
  124.             }
  125.             if (i < (MAXROOMS-2)) {
  126.                 if (rooms[i+1].is_room & R_NOTHING) {
  127.                     if (connect_rooms(i, i+2)) {
  128.                         rooms[i+1].is_room = R_CROSS;
  129.                     }
  130.                 }
  131.             }
  132.             if (i < (MAXROOMS-6)) {
  133.                 if (rooms[i+3].is_room & R_NOTHING) {
  134.                     if (connect_rooms(i, i+6)) {
  135.                         rooms[i+3].is_room = R_CROSS;
  136.                     }
  137.                 }
  138.             }
  139.             if (is_all_connected()) {
  140.                 break;
  141.             }
  142.         }
  143.         fill_out_level();
  144.     }
  145.     if (!has_amulet() && (cur_level >= AMULET_LEVEL)) {
  146.         put_amulet();
  147.     }
  148. }
  149.  
  150. make_room(rn, r1, r2, r3)
  151. short rn, r1, r2, r3;
  152. {
  153.     short left_col, right_col, top_row, bottom_row;
  154.     short width, height;
  155.     short row_offset, col_offset;
  156.     short i, j;
  157.     short ch;
  158.  
  159.     switch(rn) {
  160.     case 0:
  161.         left_col = 0;
  162.         right_col = COL1-1;
  163.         top_row = MIN_ROW;
  164.         bottom_row = ROW1-1;
  165.         break;
  166.     case 1:
  167.         left_col = COL1+1;
  168.         right_col = COL2-1;
  169.         top_row = MIN_ROW;
  170.         bottom_row = ROW1-1;
  171.         break;
  172.     case 2:
  173.         left_col = COL2+1;
  174.         right_col = DCOLS-1;
  175.         top_row = MIN_ROW;
  176.         bottom_row = ROW1-1;
  177.         break;
  178.     case 3:
  179.         left_col = 0;
  180.         right_col = COL1-1;
  181.         top_row = ROW1+1;
  182.         bottom_row = ROW2-1;
  183.         break;
  184.     case 4:
  185.         left_col = COL1+1;
  186.         right_col = COL2-1;
  187.         top_row = ROW1+1;
  188.         bottom_row = ROW2-1;
  189.         break;
  190.     case 5:
  191.         left_col = COL2+1;
  192.         right_col = DCOLS-1;
  193.         top_row = ROW1+1;
  194.         bottom_row = ROW2-1;
  195.         break;
  196.     case 6:
  197.         left_col = 0;
  198.         right_col = COL1-1;
  199.         top_row = ROW2+1;
  200.         bottom_row = DROWS - 2;
  201.         break;
  202.     case 7:
  203.         left_col = COL1+1;
  204.         right_col = COL2-1;
  205.         top_row = ROW2+1;
  206.         bottom_row = DROWS - 2;
  207.         break;
  208.     case 8:
  209.         left_col = COL2+1;
  210.         right_col = DCOLS-1;
  211.         top_row = ROW2+1;
  212.         bottom_row = DROWS - 2;
  213.         break;
  214.     case BIG_ROOM:
  215.         top_row = get_rand(MIN_ROW, MIN_ROW+5);
  216.         bottom_row = get_rand(DROWS-7, DROWS-2);
  217.         left_col = get_rand(0, 10);;
  218.         right_col = get_rand(DCOLS-11, DCOLS-1);
  219.         rn = 0;
  220.         goto B;
  221.     }
  222.     height = get_rand(4, (bottom_row-top_row+1));
  223.     width = get_rand(7, (right_col-left_col-2));
  224.  
  225.     row_offset = get_rand(0, ((bottom_row-top_row)-height+1));
  226.     col_offset = get_rand(0, ((right_col-left_col)-width+1));
  227.  
  228.     top_row += row_offset;
  229.     bottom_row = top_row + height - 1;
  230.  
  231.     left_col += col_offset;
  232.     right_col = left_col + width - 1;
  233.  
  234.     if ((rn != r1) && (rn != r2) && (rn != r3) && rand_percent(40)) {
  235.         goto END;
  236.     }
  237. B:
  238.     rooms[rn].is_room = R_ROOM;
  239.  
  240.     for (i = top_row; i <= bottom_row; i++) {
  241.         for (j = left_col; j <= right_col; j++) {
  242.             if ((i == top_row) || (i == bottom_row)) {
  243.                 ch = HORWALL;
  244.             } else if (((i != top_row) && (i != bottom_row)) &&
  245.             ((j == left_col) || (j == right_col))) {
  246.                 ch = VERTWALL;
  247.             } else {
  248.                 ch = FLOOR;
  249.             }
  250.             dungeon[i][j] = ch;
  251.         }
  252.     }
  253. END:
  254.     rooms[rn].top_row = top_row;
  255.     rooms[rn].bottom_row = bottom_row;
  256.     rooms[rn].left_col = left_col;
  257.     rooms[rn].right_col = right_col;
  258. }
  259.  
  260. connect_rooms(room1, room2)
  261. short room1, room2;
  262. {
  263.     short row1, col1, row2, col2, dir;
  264.  
  265.     if ((!(rooms[room1].is_room & (R_ROOM | R_MAZE))) ||
  266.         (!(rooms[room2].is_room & (R_ROOM | R_MAZE)))) {
  267.         return(0);
  268.     }
  269.     if (same_row(room1, room2) &&
  270.         (rooms[room1].left_col > rooms[room2].right_col)) {
  271.         put_door(&rooms[room1], LEFT, &row1, &col1);
  272.         put_door(&rooms[room2], RIGHT, &row2, &col2);
  273.         dir = LEFT;
  274.     } else if (same_row(room1, room2) &&
  275.         (rooms[room2].left_col > rooms[room1].right_col)) {
  276.         put_door(&rooms[room1], RIGHT, &row1, &col1);
  277.         put_door(&rooms[room2], LEFT, &row2, &col2);
  278.         dir = RIGHT;
  279.     } else if (same_col(room1, room2) &&
  280.         (rooms[room1].top_row > rooms[room2].bottom_row)) {
  281.         put_door(&rooms[room1], UP, &row1, &col1);
  282.         put_door(&rooms[room2], DOWN, &row2, &col2);
  283.         dir = UP;
  284.     } else if (same_col(room1, room2) &&
  285.         (rooms[room2].top_row > rooms[room1].bottom_row)) {
  286.         put_door(&rooms[room1], DOWN, &row1, &col1);
  287.         put_door(&rooms[room2], UP, &row2, &col2);
  288.         dir = DOWN;
  289.     } else {
  290.         return(0);
  291.     }
  292.  
  293.     do {
  294.         draw_simple_passage(row1, col1, row2, col2, dir);
  295.     } while (rand_percent(4));
  296.  
  297.     rooms[room1].doors[dir/2].oth_room = room2;
  298.     rooms[room1].doors[dir/2].oth_row = row2;
  299.     rooms[room1].doors[dir/2].oth_col = col2;
  300.  
  301.     rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_room = room1;
  302.     rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_row = row1;
  303.     rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_col = col1;
  304.     return(1);
  305. }
  306.  
  307. clear_level()
  308. {
  309.     short i, j;
  310.  
  311.     for (i = 0; i < MAXROOMS; i++) {
  312.         rooms[i].is_room = R_NOTHING;
  313.         for (j = 0; j < 4; j++) {
  314.             rooms[i].doors[j].oth_room = NO_ROOM;
  315.         }
  316.     }
  317.  
  318.     for (i = 0; i < MAX_TRAPS; i++) {
  319.         traps[i].trap_type = NO_TRAP;
  320.     }
  321.     for (i = 0; i < DROWS; i++) {
  322.         for (j = 0; j < DCOLS; j++) {
  323.             dungeon[i][j] = NOTHING;
  324.         }
  325.     }
  326.     detect_monster = see_invisible = 0;
  327.     being_held = bear_trap = 0;
  328.     party_room = NO_ROOM;
  329.     rogue.row = rogue.col = -1;
  330.     clear();
  331. }
  332.  
  333. put_door(rm, dir, row, col)
  334. room *rm;
  335. short dir;
  336. short *row, *col;
  337. {
  338.     short wall_width;
  339.  
  340.     wall_width = (rm->is_room & R_MAZE) ? 0 : 1;
  341.  
  342.     switch(dir) {
  343.     case UP:
  344.     case DOWN:
  345.         *row = ((dir == UP) ? rm->top_row : rm->bottom_row);
  346.         do {
  347.             *col = get_rand(rm->left_col+wall_width,
  348.                 rm->right_col-wall_width);
  349.         } while (!(dungeon[*row][*col] & (HORWALL | TUNNEL)));
  350.         break;
  351.     case RIGHT:
  352.     case LEFT:
  353.         *col = (dir == LEFT) ? rm->left_col : rm->right_col;
  354.         do {
  355.             *row = get_rand(rm->top_row+wall_width,
  356.                 rm->bottom_row-wall_width);
  357.         } while (!(dungeon[*row][*col] & (VERTWALL | TUNNEL)));
  358.         break;
  359.     }
  360.     if (rm->is_room & R_ROOM) {
  361.         dungeon[*row][*col] = DOOR;
  362.     }
  363.     if ((cur_level > 2) && rand_percent(HIDE_PERCENT)) {
  364.         dungeon[*row][*col] |= HIDDEN;
  365.     }
  366.     rm->doors[dir/2].door_row = *row;
  367.     rm->doors[dir/2].door_col = *col;
  368. }
  369.  
  370. draw_simple_passage(row1, col1, row2, col2, dir)
  371. short row1, col1, row2, col2, dir;
  372. {
  373.     short i, middle, t;
  374.  
  375.     if ((dir == LEFT) || (dir == RIGHT)) {
  376.         if (col1 > col2) {
  377.             swap(row1, row2);
  378.             swap(col1, col2);
  379.         }
  380.         middle = get_rand(col1+1, col2-1);
  381.         for (i = col1+1; i != middle; i++) {
  382.             dungeon[row1][i] = TUNNEL;
  383.         }
  384.         for (i = row1; i != row2; i += (row1 > row2) ? -1 : 1) {
  385.             dungeon[i][middle] = TUNNEL;
  386.         }
  387.         for (i = middle; i != col2; i++) {
  388.             dungeon[row2][i] = TUNNEL;
  389.         }
  390.     } else {
  391.         if (row1 > row2) {
  392.             swap(row1, row2);
  393.             swap(col1, col2);
  394.         }
  395.         middle = get_rand(row1+1, row2-1);
  396.         for (i = row1+1; i != middle; i++) {
  397.             dungeon[i][col1] = TUNNEL;
  398.         }
  399.         for (i = col1; i != col2; i += (col1 > col2) ? -1 : 1) {
  400.             dungeon[middle][i] = TUNNEL;
  401.         }
  402.         for (i = middle; i != row2; i++) {
  403.             dungeon[i][col2] = TUNNEL;
  404.         }
  405.     }
  406.     if (rand_percent(HIDE_PERCENT)) {
  407.         hide_boxed_passage(row1, col1, row2, col2, 1);
  408.     }
  409. }
  410.  
  411. same_row(room1, room2)
  412. {
  413.     return((room1 / 3) == (room2 / 3));
  414. }
  415.  
  416. same_col(room1, room2)
  417. {
  418.     return((room1 % 3) == (room2 % 3));
  419. }
  420.  
  421. add_mazes()
  422. {
  423.     short i, j;
  424.     short start;
  425.     short maze_percent;
  426.  
  427.     if (cur_level > 1) {
  428.         start = get_rand(0, (MAXROOMS-1));
  429.         maze_percent = (cur_level * 5) / 4;
  430.  
  431.         if (cur_level > 15) {
  432.             maze_percent += cur_level;
  433.         }
  434.         for (i = 0; i < MAXROOMS; i++) {
  435.             j = ((start + i) % MAXROOMS);
  436.             if (rooms[j].is_room & R_NOTHING) {
  437.                 if (rand_percent(maze_percent)) {
  438.                 rooms[j].is_room = R_MAZE;
  439.                 make_maze(get_rand(rooms[j].top_row+1, rooms[j].bottom_row-1),
  440.                     get_rand(rooms[j].left_col+1, rooms[j].right_col-1),
  441.                     rooms[j].top_row, rooms[j].bottom_row,
  442.                     rooms[j].left_col, rooms[j].right_col);
  443.                 hide_boxed_passage(rooms[j].top_row, rooms[j].left_col,
  444.                     rooms[j].bottom_row, rooms[j].right_col,
  445.                     get_rand(0, 2));
  446.                 }
  447.             }
  448.         }
  449.     }
  450. }
  451.  
  452. fill_out_level()
  453. {
  454.     short i, rn;
  455.  
  456.     mix_random_rooms();
  457.  
  458.     r_de = NO_ROOM;
  459.  
  460.     for (i = 0; i < MAXROOMS; i++) {
  461.         rn = random_rooms[i];
  462.         if ((rooms[rn].is_room & R_NOTHING) ||
  463.             ((rooms[rn].is_room & R_CROSS) && coin_toss())) {
  464.             fill_it(rn, 1);
  465.         }
  466.     }
  467.     if (r_de != NO_ROOM) {
  468.         fill_it(r_de, 0);
  469.     }
  470. }
  471.  
  472. fill_it(rn, do_rec_de)
  473. int rn;
  474. boolean do_rec_de;
  475. {
  476.     short i, tunnel_dir, door_dir, drow, dcol;
  477.     short target_room, rooms_found = 0;
  478.     short srow, scol, t;
  479.     static short offsets[4] = {-1, 1, 3, -3};
  480.     boolean did_this = 0;
  481.  
  482.     for (i = 0; i < 10; i++) {
  483.         srow = get_rand(0, 3);
  484.         scol = get_rand(0, 3);
  485.         t = offsets[srow];
  486.         offsets[srow] = offsets[scol];
  487.         offsets[scol] = t;
  488.     }
  489.     for (i = 0; i < 4; i++) {
  490.  
  491.         target_room = rn + offsets[i];
  492.  
  493.         if (((target_room < 0) || (target_room >= MAXROOMS)) ||
  494.             (!(same_row(rn,target_room) || same_col(rn,target_room))) ||
  495.             (!(rooms[target_room].is_room & (R_ROOM | R_MAZE)))) {
  496.             continue;
  497.         }
  498.         if (same_row(rn, target_room)) {
  499.             tunnel_dir = (rooms[rn].left_col < rooms[target_room].left_col) ?
  500.                 RIGHT : LEFT;
  501.         } else {
  502.             tunnel_dir = (rooms[rn].top_row < rooms[target_room].top_row) ?
  503.                 DOWN : UP;
  504.         }
  505.         door_dir = ((tunnel_dir + 4) % DIRS);
  506.         if (rooms[target_room].doors[door_dir/2].oth_room != NO_ROOM) {
  507.             continue;
  508.         }
  509.         if (((!do_rec_de) || did_this) ||
  510.             (!mask_room(rn, &srow, &scol, TUNNEL))) {
  511.             srow = (rooms[rn].top_row + rooms[rn].bottom_row) / 2;
  512.             scol = (rooms[rn].left_col + rooms[rn].right_col) / 2;
  513.         }
  514.         put_door(&rooms[target_room], door_dir, &drow, &dcol);
  515.         rooms_found++;
  516.         draw_simple_passage(srow, scol, drow, dcol, tunnel_dir);
  517.         rooms[rn].is_room = R_DEADEND;
  518.         dungeon[srow][scol] = TUNNEL;
  519.  
  520.         if ((i < 3) && (!did_this)) {
  521.             did_this = 1;
  522.             if (coin_toss()) {
  523.                 continue;
  524.             }
  525.         }
  526.         if ((rooms_found < 2) && do_rec_de) {
  527.             recursive_deadend(rn, offsets, srow, scol);
  528.         }
  529.         break;
  530.     }
  531. }
  532.  
  533. recursive_deadend(rn, offsets, srow, scol)
  534. short rn;
  535. short *offsets;
  536. short srow, scol;
  537. {
  538.     short i, de;
  539.     short drow, dcol, tunnel_dir;
  540.  
  541.     rooms[rn].is_room = R_DEADEND;
  542.     dungeon[srow][scol] = TUNNEL;
  543.  
  544.     for (i = 0; i < 4; i++) {
  545.         de = rn + offsets[i];
  546.         if (((de < 0) || (de >= MAXROOMS)) ||
  547.             (!(same_row(rn, de) || same_col(rn, de)))) {
  548.             continue;
  549.         }
  550.         if (!(rooms[de].is_room & R_NOTHING)) {
  551.             continue;
  552.         }
  553.         drow = (rooms[de].top_row + rooms[de].bottom_row) / 2;
  554.         dcol = (rooms[de].left_col + rooms[de].right_col) / 2;
  555.         if (same_row(rn, de)) {
  556.             tunnel_dir = (rooms[rn].left_col < rooms[de].left_col) ?
  557.                 RIGHT : LEFT;
  558.         } else {
  559.             tunnel_dir = (rooms[rn].top_row < rooms[de].top_row) ?
  560.                 DOWN : UP;
  561.         }
  562.         draw_simple_passage(srow, scol, drow, dcol, tunnel_dir);
  563.         r_de = de;
  564.         recursive_deadend(de, offsets, drow, dcol);
  565.     }
  566. }
  567.  
  568. boolean
  569. mask_room(rn, row, col, mask)
  570. short rn;
  571. short *row, *col;
  572. unsigned short mask;
  573. {
  574.     short i, j;
  575.  
  576.     for (i = rooms[rn].top_row; i <= rooms[rn].bottom_row; i++) {
  577.         for (j = rooms[rn].left_col; j <= rooms[rn].right_col; j++) {
  578.             if (dungeon[i][j] & mask) {
  579.                 *row = i;
  580.                 *col = j;
  581.                 return(1);
  582.             }
  583.         }
  584.     }
  585.     return(0);
  586. }
  587.  
  588. make_maze(r, c, tr, br, lc, rc)
  589. short r, c, tr, br, lc, rc;
  590. {
  591.     char dirs[4];
  592.     short i, t;
  593.  
  594.     dirs[0] = UP;
  595.     dirs[1] = DOWN;
  596.     dirs[2] = LEFT;
  597.     dirs[3] = RIGHT;
  598.  
  599.     dungeon[r][c] = TUNNEL;
  600.  
  601.     if (rand_percent(33)) {
  602.         for (i = 0; i < 10; i++) {
  603.             short t1, t2;
  604.  
  605.             t1 = get_rand(0, 3);
  606.             t2 = get_rand(0, 3);
  607.  
  608.             swap(dirs[t1], dirs[t2]);
  609.         }
  610.     }
  611.     for (i = 0; i < 4; i++) {
  612.         switch(dirs[i]) {
  613.         case UP:
  614.             if (((r-1) >= tr) &&
  615.                 (dungeon[r-1][c] != TUNNEL) &&
  616.                 (dungeon[r-1][c-1] != TUNNEL) &&
  617.                 (dungeon[r-1][c+1] != TUNNEL) &&
  618.                 (dungeon[r-2][c] != TUNNEL)) {
  619.                 make_maze((r-1), c, tr, br, lc, rc);
  620.             }
  621.             break;
  622.         case DOWN:
  623.             if (((r+1) <= br) &&
  624.                 (dungeon[r+1][c] != TUNNEL) &&
  625.                 (dungeon[r+1][c-1] != TUNNEL) &&
  626.                 (dungeon[r+1][c+1] != TUNNEL) &&
  627.                 (dungeon[r+2][c] != TUNNEL)) {
  628.                 make_maze((r+1), c, tr, br, lc, rc);
  629.             }
  630.             break;
  631.         case LEFT:
  632.             if (((c-1) >= lc) &&
  633.                 (dungeon[r][c-1] != TUNNEL) &&
  634.                 (dungeon[r-1][c-1] != TUNNEL) &&
  635.                 (dungeon[r+1][c-1] != TUNNEL) &&
  636.                 (dungeon[r][c-2] != TUNNEL)) {
  637.                 make_maze(r, (c-1), tr, br, lc, rc);
  638.             }
  639.             break;
  640.         case RIGHT:
  641.             if (((c+1) <= rc) &&
  642.                 (dungeon[r][c+1] != TUNNEL) &&
  643.                 (dungeon[r-1][c+1] != TUNNEL) &&
  644.                 (dungeon[r+1][c+1] != TUNNEL) &&
  645.                 (dungeon[r][c+2] != TUNNEL)) {
  646.                 make_maze(r, (c+1), tr, br, lc, rc);
  647.             }
  648.             break;
  649.         }
  650.     }
  651. }
  652.  
  653. hide_boxed_passage(row1, col1, row2, col2, n)
  654. short row1, col1, row2, col2, n;
  655. {
  656.     short i, j, t;
  657.     short row, col, row_cut, col_cut;
  658.     short h, w;
  659.  
  660.     if (cur_level > 2) {
  661.         if (row1 > row2) {
  662.             swap(row1, row2);
  663.         }
  664.         if (col1 > col2) {
  665.             swap(col1, col2);
  666.         }
  667.         h = row2 - row1;
  668.         w = col2 - col1;
  669.  
  670.         if ((w >= 5) || (h >= 5)) {
  671.             row_cut = ((h >= 2) ? 1 : 0);
  672.             col_cut = ((w >= 2) ? 1 : 0);
  673.  
  674.             for (i = 0; i < n; i++) {
  675.                 for (j = 0; j < 10; j++) {
  676.                     row = get_rand(row1 + row_cut, row2 - row_cut);
  677.                     col = get_rand(col1 + col_cut, col2 - col_cut);
  678.                     if (dungeon[row][col] == TUNNEL) {
  679.                         dungeon[row][col] |= HIDDEN;
  680.                         break;
  681.                     }
  682.                 }
  683.             }
  684.         }
  685.     }
  686. }
  687.  
  688. put_player(nr)
  689. short nr;        /* try not to put in this room */
  690. {
  691.     short rn = nr, misses;
  692.     short row, col;
  693.  
  694.     for (misses = 0; ((misses < 2) && (rn == nr)); misses++) {
  695.         gr_row_col(&row, &col, (FLOOR | TUNNEL | OBJECT | STAIRS));
  696.         rn = get_room_number(row, col);
  697.     }
  698.     rogue.row = row;
  699.     rogue.col = col;
  700.  
  701.     if (dungeon[rogue.row][rogue.col] & TUNNEL) {
  702.         cur_room = PASSAGE;
  703.     } else {
  704.         cur_room = rn;
  705.     }
  706.     if (cur_room != PASSAGE) {
  707.         light_up_room(cur_room);
  708.     } else {
  709.         light_passage(rogue.row, rogue.col);
  710.     }
  711.     wake_room(get_room_number(rogue.row, rogue.col), 1, rogue.row, rogue.col);
  712.     if (new_level_message) {
  713.         message(new_level_message, 0);
  714.         new_level_message = 0;
  715.     }
  716.     mvaddch(rogue.row, rogue.col, rogue.fchar);
  717. }
  718.  
  719. drop_check()
  720. {
  721.     if (wizard) {
  722.         return(1);
  723.     }
  724.     if (dungeon[rogue.row][rogue.col] & STAIRS) {
  725.         if (levitate) {
  726.             message("you're floating in the air!", 0);
  727.             return(0);
  728.         }
  729.         return(1);
  730.     }
  731.     message("I see no way down", 0);
  732.     return(0);
  733. }
  734.  
  735. check_up()
  736. {
  737.     if (!wizard) {
  738.         if (!(dungeon[rogue.row][rogue.col] & STAIRS)) {
  739.             message("I see no way up", 0);
  740.             return(0);
  741.         }
  742.         if (!has_amulet()) {
  743.             message("your way is magically blocked", 0);
  744.             return(0);
  745.         }
  746.     }
  747.     new_level_message = "you feel a wrenching sensation in your gut";
  748.     if (cur_level == 1) {
  749.         win();
  750.     } else {
  751.         cur_level -= 2;
  752.         return(1);
  753.     }
  754.     return(0);
  755. }
  756.  
  757. add_exp(e, promotion)
  758. int e;
  759. boolean promotion;
  760. {
  761.     char mbuf[40];
  762.     short new_exp;
  763.     short i, hp;
  764.  
  765.     rogue.exp_points += e;
  766.  
  767.     if (rogue.exp_points >= level_points[rogue.exp-1]) {
  768.         new_exp = get_exp_level(rogue.exp_points);
  769.         if (rogue.exp_points > MAX_EXP) {
  770.             rogue.exp_points = MAX_EXP + 1;
  771.         }
  772.         for (i = rogue.exp+1; i <= new_exp; i++) {
  773.             sprintf(mbuf, "welcome to level %d", i);
  774.             message(mbuf, 0);
  775.             if (promotion) {
  776.                 hp = hp_raise();
  777.                 rogue.hp_current += hp;
  778.                 rogue.hp_max += hp;
  779.             }
  780.             rogue.exp = i;
  781.             print_stats(STAT_HP | STAT_EXP);
  782.         }
  783.     } else {
  784.         print_stats(STAT_EXP);
  785.     }
  786. }
  787.  
  788. get_exp_level(e)
  789. long e;
  790. {
  791.     short i;
  792.  
  793.     for (i = 0; i < (MAX_EXP_LEVEL - 1); i++) {
  794.         if (level_points[i] > e) {
  795.             break;
  796.         }
  797.     }
  798.     return(i+1);
  799. }
  800.  
  801. hp_raise()
  802. {
  803.     int hp;
  804.  
  805.     hp = (wizard ? 10 : get_rand(3, 10));
  806.     return(hp);
  807. }
  808.  
  809. show_average_hp()
  810. {
  811.     char mbuf[80];
  812.     float real_average;
  813.     float effective_average;
  814.  
  815.     if (rogue.exp == 1) {
  816.         real_average = effective_average = 0.00;
  817.     } else {
  818.         real_average = (float)
  819.             ((rogue.hp_max - extra_hp - INIT_HP) + less_hp) / (rogue.exp - 1);
  820.         effective_average = (float) (rogue.hp_max - INIT_HP) / (rogue.exp - 1);
  821.  
  822.     }
  823.     sprintf(mbuf, "R-Hp: %.2f, E-Hp: %.2f (!: %d, V: %d)", real_average,
  824.         effective_average, extra_hp, less_hp);
  825.     message(mbuf, 0);
  826. }
  827.  
  828. mix_random_rooms()
  829. {
  830.     short i, t;
  831.     short x, y;
  832.  
  833.     for (i = 0; i < (3 * MAXROOMS); i++) {
  834.         do {
  835.             x = get_rand(0, (MAXROOMS-1));
  836.             y = get_rand(0, (MAXROOMS-1));
  837.         } while (x == y);
  838.         swap(random_rooms[x], random_rooms[y]);
  839.     }
  840. }
  841.